﻿using Microsoft.Win32.SafeHandles;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading;

namespace UtilZ.Dotnet.Ex.Base
{
    /// <summary>
    /// WaitHandleEx扩展类
    /// </summary>
    public static class WaitHandleEx
    {
        /// <summary>
        /// 对Token,WaitHandle方法的包装,Blocks the current thread until the current System.Threading.WaitHandle receives a signal. 
        /// </summary>
        /// <param name="waitHandle">WaitHandle</param>
        /// <returns>true if the current instance receives a signal. 
        /// If the current instance is never signaled, 
        /// System.Threading.WaitHandle.WaitOne(System.Int32,System.Boolean) never returns.</returns>
        public static bool WaitOne(this WaitHandle waitHandle)
        {
            try
            {
                return waitHandle.WaitOne();
            }
            catch (AbandonedMutexException)
            {
                return false;
            }
            catch (ObjectDisposedException)
            {
                return false;
            }
            catch (InvalidOperationException)
            {
                return false;
            }
        }

        /// <summary>
        /// 阻止当前线程，直到当前 System.Threading.WaitHandle 收到信号，同时使用 32 位带符号整数指定时间间隔（以毫秒为单位）
        /// </summary>
        /// <param name="waitHandle">WaitHandle</param>
        /// <param name="millisecondsTimeout">等待的毫秒数，或为 System.Threading.Timeout.Infinite (-1)，表示无限期等待</param>
        /// <returns></returns>
        public static bool WaitOne(this WaitHandle waitHandle, int millisecondsTimeout)
        {
            try
            {
                return waitHandle.WaitOne(millisecondsTimeout);
            }
            catch (ObjectDisposedException)
            {
                return false;
            }
        }

        /// <summary>
        /// 对Token,WaitHandle方法的包装,Blocks the current thread until the current System.Threading.WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval in milliseconds.
        /// </summary>
        /// <param name="waitHandle">WaitHandle</param>
        /// <param name="timeout">A System.TimeSpan that represents the number of milliseconds to wait, or a System.TimeSpan that represents -1 milliseconds to wait indefinitely</param>
        /// <returns>true if the current instance receives a signal; otherwise, false</returns>
        public static bool WaitOne(this WaitHandle waitHandle, TimeSpan timeout)
        {
            try
            {
                return waitHandle.WaitOne(timeout);
            }
            catch (AbandonedMutexException)
            {
                return false;
            }
            catch (ObjectDisposedException)
            {
                return false;
            }
            catch (InvalidOperationException)
            {
                return false;
            }
        }
    }
}
